﻿using EasyCore.Core.Modules;
using EasyCore.Reflection;
using EasyCore.UnifyResult;
using EasyCore.UnifyResult.Exceptions;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data.OscarClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EasyCore.Core.Builders
{
    public class ModuleBuilder : IModuleBuilder
    {
        /// <summary>
        /// 系统已经加载的所有模块
        /// </summary>
        public List<EasyModule> Modules { get; set; }

        /// <summary>
        /// 获取 服务集合
        /// </summary>
        public IServiceCollection Services { get; }


        /// <summary>
        /// 构造函数
        /// </summary>
        public ModuleBuilder(IServiceCollection services)
        {
            Modules = new List<EasyModule>(); //初始化模块容器
            Services = services;
            //AllModules = GetAllModules();//获得所有模块
        }

        /// <summary>
        /// 添加指定模块
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public IModuleBuilder AddModule<T>() where T : EasyModule
        {
            Type type = typeof(T);
            return AddModule(type);
        }

        /// <summary>
        /// 添加所有模块
        /// </summary>
        /// <param name="excludeModuleTypes"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public IModuleBuilder AddModules(params Type[] excludeModuleTypes)
        {
            var allModules = GetAllModules();
            var exceptModules = allModules.Where(m => excludeModuleTypes.Contains(m.GetType())).ToArray();
            allModules = allModules.Except(exceptModules).ToList();
            foreach (EasyModule easyModule in allModules)
            {
                AddModule(easyModule.GetType());
            }
            return this;
        }

        /// <summary>
        ///获得程序集的所有模块
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        private List<EasyModule> GetAllModules()
        {
            //需要排除已经被继承的Pack实类
            Type[] types = AssemblyManager.FindTypesByBase<EasyModule>();
            Type[] moduleTypes = types.Select(m => m.BaseType).Where(m => m != null && !m.IsAbstract).ToArray();
            moduleTypes = types.Except(moduleTypes).ToArray();
            return moduleTypes.Select(m => (EasyModule)Activator.CreateInstance(m)).OrderBy(m => m.GetType().FullName).ToList();
            //  .OrderBy(m => m.Level).ThenBy(m => m.Order)
        }

        /// <summary>
        /// 添加单个模块
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        /// <exception cref="OperateBusinessException"></exception>
        private IModuleBuilder AddModule(Type type)
        {
            if (!(type.IsBaseOn(typeof(EasyModule)) && type.IsAbstract))
            {
                throw new BusinessException($"要加载的Module类型“{type}”不派生于基类 EasyModule");
            }
            if (Modules.Any(m => m.GetType() == type))
            {
                //当已添加该类型时，则返回
                return this;
            }
            //判断该类是否可实例化
            //添加依赖模块
            //添加模块
            var easyModule = (EasyModule)Activator.CreateInstance(type);//实例化
            easyModule.AddServices(Services); //添加模块服务
            Modules.Add(easyModule);
            return this;
        }
    }
}
